<?php

namespace app\common\model;

use think\facade\Validate;
use think\Model;

class BaseModels extends Model
{
    // 指定AND查询条件
    private static $wheres = '';
    // 指定RAW查询条件
    private static $whereRaws = '';
    // 字段截取
    private static $fields = '';
    // 排序
    private static $orders = '';
    // 指定OR查询条件
    private static $whereOr = '';
    // 指定withs查询 = '';
    private static $withs = [];
    // 是否查询加锁
    private static $locks = false;
    // 错误信息
    private static $error = '';

    public static function locks($locks = false)
    {
        if (!empty($locks)){
            self::$locks = $locks;
        }
        return self::$locks;
    }

    public static function wheres($wheres = '')
    {
        if (!empty($wheres)){
            self::$wheres = $wheres;
        }
        return self::$wheres;
    }

    public static function whereRaws($whereRaws = '')
    {
        if (!empty($whereRaws)){
            self::$whereRaws = $whereRaws;
        }
        return self::$whereRaws;
    }

    public static function fields($fields = '')
    {
        if (!empty($fields)){
            self::$fields = $fields;
        }
        return self::$fields;
    }
    public static function orders($orders = '')
    {
        if (!empty($orders)){
            self::$orders = $orders;
        }
        return self::$orders;
    }

    public static function whereOrs($whereOrs = '')
    {
        if (!empty($whereOrs)){
            self::$whereOr = $whereOrs;
        }
        return self::$whereOr;
    }

    public static function withs($withs = [])
    {
        if (!empty($withs)){
            self::$withs = $withs;
        }
        return self::$withs;
    }

    /**
     * 获取单个字段数据
     * @param string|array $where
     * @param string|array $field
     * @param string $order
     * @param string|array $whereOr
     * @return string
     */
    public function getField($where = '', $field = '', string $order = '', $whereOr = ''): string
    {
        if (empty($where) && empty($whereOr)) return '';
        if (empty($field)) return '';
        $value = $this->query($where, '', $order, $whereOr)->value($field);
        return empty($value) ? '' : $value;
    }

    /**
     * 更新单条数据
     * @param string|array $where
     * @param array $data
     * @return bool
     */
    public function setField($where = '',array $data = []): bool
    {
        if (empty($data)) return false;
        return $this->query($where)->save($data);
    }

    /**
     * 获取单条数据
     * @param string|array $where
     * @param string|array $field
     * @param string $order
     * @param string|array $whereOr
     * @return array|null|Model
     */
    public function getFind(string $where = '', string $field = '', string $order = '', string $whereOr = ''): array
    {
        if (empty($where) && empty($whereOr)) return [];
        $query = $this->query($where, $field, $order, $whereOr);
        return $query->findOrEmpty()->toArray();
    }

    /**
     * 更新和修改操作
     * @param array $data
     * @param bool $autoValidate
     * @param bool $all
     * @param bool $getLastInsID
     * @return bool|string
     */
    public function operation(array $data = [] , bool $autoValidate = true, bool $all = false, bool $getLastInsID = false)
    {
        // $all 是否批量操作
        if ($autoValidate){
            $validate = false;
            if (is_array($autoValidate)){
                if (!empty($autoValidate['rule'])){
                    $validate = Validate::make($autoValidate['rule'], $autoValidate['message']);
                }
            }else{
                $class = '\\app\\common\\validate\\' . $this->getValidator();
                if (class_exists($class)) {
                    $validate = new $class();
                }
            }
            if (!$validate){
                return self::setError('验证失败');
            }
            // 是否批量验证
            if ($all){
                foreach ($data as $val){
                    if (!$validate->check($val)){
                        return self::setError($validate->getError());
                    }
                }
            }else{
                if (!$validate->check($data)){
                    return self::setError($validate->getError());
                }
            }
        }
        if ($all){
            $rows = $this->insertAll($data);
        }else{
            if (empty($data[$this->pk])){
                $rows = self::create($data);
                if ($getLastInsID === true){
                    return $this->getLastInsID();
                }
            }else{
                $rows = self::update($data);
            }
        }
        if (empty($rows)){
            return false;
        }
        return true;
    }

    /**
     * 状态操作设置
     * @param string|array $where
     * @param string $field
     * @param int $value
     * @param int $default
     * @return bool
     */
    public function status($where = '', string $field = 'status', int $value = 0 , int $default = 1): bool
    {
        $wheres = empty($where) ? self::wheres() : $where;
        $fields = empty($field) ? self::fields() : $field;
        if (empty($wheres)) return false;
        // 数据查询
        $query = $this->db();
        // 批量修改
        if (is_array($wheres)){
            $keys = array_keys($wheres);
            if ($keys['0'] === 0){
                foreach ($wheres as $val){
                    $status = self::getField($val, $fields);
                    $new_value = $status == $default ? $value : $default;
                    // 主键查询
                    if (is_numeric($val)){
                        $rows = $query->where($this->pk, $val)->update([$fields=>$new_value]);
                    }else{
                        $rows = $query->where($val)->update([$fields=>$new_value]);
                    }
                    if (empty($rows)){
                        return false;
                    }
                }
            }else{
                $status = self::getField($wheres, $fields);
                $new_value = $status == $default ? $value : $default;
                $rows = $query->where($wheres)->update([$fields=>$new_value]);
            }
        }elseif (is_numeric($wheres)){
            // 主键查询
            $status = self::getField($wheres, $fields);
            $new_value = $status == $default ? $value : $default;
            $rows = $query->where($this->pk, $wheres)->update([$fields=>$new_value]);
        }else{
            $status = self::getField($wheres, $fields);
            $new_value = $status == $default ? $value : $default;
            $rows = $query->where($wheres)->update([$fields=>$new_value]);
        }
        if (empty($rows)){
            return false;
        }
        return true;
    }

    /**
     * 删除操作
     * @param string|array $where
     * @return bool
     */
    public function remove($where = ''): bool
    {
        $wheres = empty($where) ? self::wheres() : $where;
        if (empty($wheres)) return false;
        // 数据查询
        $query = $this->db();
        // 批量删除
        if (is_array($wheres)){
            $keys = array_keys($wheres);
            if ($keys['0'] === 0){
                foreach ($wheres as $val){
                    // 主键查询
                    if (is_numeric($val)){
                        $rows = $query->where($this->pk, $val)->delete();
                    }else{
                        $rows = $query->where($val)->delete();
                    }
                    if (empty($rows)){
                        return false;
                    }
                }
            }else{
                $rows = $query->where($wheres)->delete();
            }
        }elseif (is_numeric($wheres)){
            // 主键查询
            $rows = $query->where($this->pk, $wheres)->delete();
        }else{
            $rows = $query->where($wheres)->delete();
        }
        if (empty($rows)){
            return false;
        }
        return true;
    }

    /**
     * 检测是否存在
     * @param string|array $where
     * @return bool
     */
    public function getExists($where = ''): bool
    {
        return $this->countExists($where);
    }

    /**
     * 数量统计
     * @param string|array $where
     * @return int
     */
    public function getCount($where = ''): int
    {
        return $this->countExists($where, false);
    }

    public function countExists($where = '', $is_bool = true)
    {
        $wheres = empty($where) ? self::wheres() : $where;
        // 数据查询
        $query = $this->db();
        // 存在where查询
        if (!empty($wheres)){
            // 主键查询
            if (is_numeric($wheres)){
                $query = $query->where($this->pk, $wheres);
            }else{
                $query = $query->where($wheres);
            }
        }
        $rows = $query->count();
        if ($is_bool){
            if (empty($rows)){
                return false;
            }
            return true;
        }
        return $rows;
    }

    /**
     * @param string|array $where
     * @param string $field
     * @return float
     */
    public function getSum($where = '', string $field = '')
    {
        $wheres = empty($where) ? self::wheres() : $where;
        if (empty($field)) return 0;
        // 数据查询
        $query = $this->db();
        // 存在where查询
        if (!empty($wheres)){
            // 主键查询
            if (is_numeric($wheres)){
                $query = $query->where($this->pk, $wheres);
            }else{
                $query = $query->where($wheres);
            }
        }
        return $query->sum($field);
    }

    /**
     * 获取列表数据
     * @param string|array $where
     * @param string|int $limit
     * @param string $order
     * @param string|array $field
     * @param string|array $whereOr
     * @return array
     */
    public function getList($where = '', $limit = '', string $order = '', $field = '', $whereOr = ''): array
    {
        $query = $this->query($where, $field, $order, $whereOr);
        if (!empty($limit)){
            if (is_numeric($limit)){
                $query = $query->limit($limit);
            }else{
                $limit_length = explode(',', $limit);
                $limit = intval($limit_length[0]);
                $length = intval($limit_length[1]);;
                $query = $query->limit($limit, $length);
            }
        }
        $list = $query->select()->toArray();
        if (!empty($list)){
            foreach ($list as &$val){
                if (isset($val['create_time']) && is_numeric($val['create_time'])){
                    $val['create_time'] = date('Y-m-d H:i', $val['create_time']);
                }
                if (isset($val['update_time']) && is_numeric($val['update_time'])){
                    $val['update_time'] = date('Y-m-d H:i', $val['update_time']);
                }
            }
        }
        return $list;
    }

    /**
     * 获取列表分页数据
     * @param string|array $where
     * @param string|int $limit
     * @param string $order
     * @param string|array $field
     * @param string|array $whereOr
     * @return array
     */
    public function getLists($where = '', $limit = 1, string $order = '', $field = '', $whereOr = ''): array
    {
        $query = $this->query($where, $field, $order, $whereOr);
        // 分页数据处理
        $count = $query->count();
        $list = $query->paginate($limit);
        $page = $list->render();
        $data = $list->toArray();
        if (!empty($data['data'])){
            if (is_array($data['data'])){
                foreach ($data['data'] as &$val){
                    if (isset($val['create_time']) && is_numeric($val['create_time'])){
                        $val['create_time'] = date('Y-m-d H:i', $val['create_time']);
                    }
                    if (isset($val['update_time']) && is_numeric($val['update_time'])){
                        $val['update_time'] = date('Y-m-d H:i', $val['update_time']);
                    }
                }
            }
        }
        return [
            'count'=>$count,
            'page'=>$page,
            'list'=>$data['data']
        ];
    }

    // 数据查询
    public function query($where = '', $field = '', $order = '', $whereOr = '')
    {
        $wheres = empty($where) ? self::wheres() : $where;
        $fields = empty($field) ? self::fields() : $field;
        $orders = empty($order) ? self::orders() : $order;
        $whereOrs = empty($whereOr) ? self::whereOrs() : $whereOr;
        $withs = self::withs();
        $whereRaws = self::whereRaws();
        // 数据查询
        $query = $this->db();
        // 存在withJoin查询
        if (!empty($withs)){
            if (is_array($withs)){
                if (count($withs) != count($withs, 1)){
                    $query->withJoin($withs['0'], $withs['1']);
                }else{
                    $query->with($withs);
                }
            }
        }
        // 是否查询加锁
        if (self::$locks){
            $query = $query->lock(self::$locks);
        }
        // 存在where查询
        if (!empty($wheres)){
            // 主键查询
            if (is_numeric($wheres)){
                $query = $query->where($this->pk, $wheres);
            }else{
                $query = $query->where($wheres);
            }
        }
        // 存在whereRaw查询
        if (!empty($whereRaws)){
            if (is_array($whereRaws)){
                foreach ($whereRaws as $val){
                    $query = $query->whereRaw($val);
                }
            }else{
                $query = $query->whereRaw($whereRaws);
            }
        }
        // 存在whereOr查询
        if (!empty($whereOrs)){
            $query = $query->where($whereOrs);
        }
        // 存在order排序
        if (!empty($orders)){
            $query = $query->order($orders);
        }
        // 指定字段查询
        if (!empty($fields)){
            // 排除查询
            $except = false;
            if (is_array($fields)){
                $except = end($fields);
                if ($except === true){
                    $fields = reset($fields);
                }else{
                    $fields = implode(',', $fields);
                }
            }
            if ($except === true){
                $query->withoutField($fields);
            }else{
                $query->field($fields);
            }
        }
        // 重置查询参数
        self::resetQuery();
        // 返回查询语句
        return $query;
    }

    // 重置查询参数
    protected static function resetQuery(): void
    {
        self::$wheres = '';
        self::$whereRaws = '';
        self::$fields = '';
        self::$orders = '';
        self::$whereOr = '';
        self::$withs = [];
        self::$locks = false;
    }

    public function setInc($where = '', $field = '', $number = 1): bool
    {
        return $this->setIncDec(1, $where, $field, $number);
    }

    public function setDec($where = '', $field = '', $number = 1): bool
    {
        return $this->setIncDec(2, $where, $field, $number);
    }

    public function setIncDec($type = 1, $where = '', $field = '', $number = 0): bool
    {
        if (empty($field)) return false;
        $query = $this->query($where, $field);
        if ($type == 1){
            $query = $query->inc($field, $number);
        }else{
            $query = $query->dec($field, $number);
        }
        if ($query->update()){
            return true;
        }
        return false;
    }

    // 获取验证类
    protected function getValidator()
    {
        return str_replace('_', '', ucwords($this->name, '_'));
    }

    // 获取错误提示信息
    public static function setError(string $error = ''): bool
    {
        self::error($error);
        return false;
    }

    // 获取错误提示信息
    public function getError(): string
    {
        return self::error();
    }

    protected static function error(string $error = ''): bool
    {
        if (!empty($error)){
            self::$error = $error;
        }
        return self::$error;
    }
}